﻿using SuperX.Common;
using SuperX.Common.APIManager;
using SuperX.Common.AppConfiguration;
using SuperX.Common.BasicService;
using SuperX.Common.Helper;
using SuperX.Common.Log;
using SuperX.ProjectCore;
using SuperX.DataCenterService.RabbitMQ.Model;
using SuperX.Helper;
using SuperX.Helper.Model;
using SuperX.Helper.ServiceResponse;
using SuperX.Helper.TreeUtil;
using SuperX.MiddlewareBase;
using SuperX.SuperSocket;
using SuperX.SuperSocket.Socket.Rpc;
using Microsoft.Scripting.Utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace SuperX.DataCenterService
{
    [PythonScript(label = "DataCenterController", apply = "DataCenterController", type = "keyword", detail = "")]
    public class DataCenterController : DynamicApiController
    {
        private const string _parentNode = "Server";
        private readonly DataCenterServer _server;
        private IProject _project = BasicServiceManager.GetProjService().Project;

        public DataCenterController(DataCenterServer server)
        {
            _server = server;
            Name = nameof(DataCenterController);
        }

        public DataCenterServer DataCenter { get; set; }

        [WebApi("获取RabbitMQ树", "主机对象", "返回Code")]
        public ApiResponse<List<BaseTreeModel>> GetRabbitMQTree(string groupName = "")
        {
            List<BaseTreeModel> treeItem = new List<BaseTreeModel>();
            foreach (var host in _server.Config.RabbitMQHosts)
            {
                BaseTreeModel tree = new BaseTreeModel();
                tree.Name = host.Name;
                tree.Parentkey = _parentNode;
                tree.Type = (int)DriverTree.Driver;
                tree.Key = host.FullName;
                treeItem.Add(tree);

                foreach (var group in host.ChannelGroup.Values)
                {
                    treeItem.Add(new BaseTreeModel()
                    {
                        Name = group.Name,
                        Key = group.Key,
                        Parentkey = host.FullName,
                        Type = (int)DriverTree.DriverGroup
                    });
                }
            }
            if (!string.IsNullOrEmpty(groupName))
            {
                string[] parentkeys = treeItem.Where(x => x.Name.Contains(groupName)).Select(x => x.Parentkey).ToArray();
                treeItem = treeItem.Where(x => x.Name.Contains(groupName) || parentkeys.Contains(x.Key)).ToList();
            }
            treeItem.Add(new BaseTreeModel() { Parentkey = "0", Key = _parentNode, Type = 0, Name = "服务" });
            var res = TreeHelper.BulidTreeByRecursive(treeItem, new List<BaseTreeModel>(), "0");
            return res.ToResponse();
        }

        [WebApi("添加分组", "", "")]
        public ApiResponse<bool> AddGroup(string mqHostFullName, string groupKey)
        {
            var host = _server.Config.RabbitMQHosts.Values.Where(x => x.FullName == mqHostFullName).FirstOrDefault();
            if (host == null) return ApiResponse<bool>.Fail("未找到改主机！");
            host.ChannelGroup.Add(groupKey, new BaseTreeModel() { Name = groupKey, Key = groupKey });
            return ApiResponse<bool>.Success(data: true);
        }

        [WebApi("删除分组", "", "")]
        public ApiResponse<bool> DelGroup(string mqHostFullName, string groupKey)
        {
            var host = _server.Config.RabbitMQHosts.Values.Where(x => x.FullName == mqHostFullName).FirstOrDefault();
            if (host == null || !host.ChannelGroup.ContainsKey(groupKey)) return ApiResponse<bool>.Fail();
            host.ChannelGroup.Remove(groupKey);
            var channels = host.ChannelItems.Values.Where(x => x.GroupKey == groupKey).ToList();
            foreach (var item in channels)
            {
                host.ChannelItems.Remove(item);
            }
            return ApiResponse<bool>.Success(data: true);
        }

        [WebApi("修改分组", "", "")]
        public ApiResponse<bool> EditGroup(string mqHostFullName, string oldGroupKey, string groupKey)
        {
            var host = _server.Config.RabbitMQHosts.Values.Where(x => x.FullName == mqHostFullName).FirstOrDefault();
            if (host == null || !host.ChannelGroup.ContainsKey(oldGroupKey)) return ApiResponse<bool>.Fail();
            host.ChannelGroup.Remove(oldGroupKey);
            host.ChannelGroup.Add(groupKey, new BaseTreeModel() { Name = groupKey, Key = groupKey });
            var channels = host.ChannelItems.Values.Where(x => x.GroupKey == oldGroupKey).ToList();
            foreach (var item in channels)
            {
                item.GroupKey = groupKey;
            }
            return ApiResponse<bool>.Success(data: true);
        }

        [WebApi("新增RabbitMQ主机", "主机对象", "返回Code")]
        public ApiResponse<string> AddRabbiMQHost(RabbitHostConfig hostItem)
        {
            Helper.Validation.ValidationMain.ScanIsValid(hostItem);
            hostItem.Password = Encryption.Encode(hostItem.Password);
            _server.Config.RabbitMQHosts.Add(hostItem);
            return ApiResponse<string>.Success("添加成功！");
        }

        [WebApi("删除RabbiMQ主机", "主机名称", "返回Code")]
        public ApiResponse<string> DelRabbiMQHost(string hostName)
        {
            var hosts = _server.Config.RabbitMQHosts;
            var host = hosts[hostName];
            if (host == null) return ApiResponse<string>.Fail("未找到该主机，删除失败！");
            else hosts.Remove(host);
            return ApiResponse<string>.Success("删除成功！");
        }

        [WebApi("更改RabbitMQ主机", "主机对象", "返回ApiResult")]
        public ApiResponse<string> UpdateRabbiMQHost(string hostFullName, RabbitHostConfig hostItem)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                var skip = "";
                Helper.Validation.ValidationMain.ScanIsValid(hostItem);
                if (hostItem.Password == "******") skip += ",Password";
                else hostItem.Password = Encryption.Encode(hostItem.Password);
                ConfigReflectionHelper.AutoMapping(server, hostItem, skip: "ChannelItems,Item,FullName,ChannelGroup" + skip);
                return ApiResponse<string>.Success("更新成功！");
            }
            return ApiResponse<string>.Fail("未找到该主机，更新失败！");
        }

        [WebApi("获取RabbitMQ主机", "", "返回ApiResult")]
        public ApiResponse<JObject> GetRabbiMQHost(string hostFullName)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                var result = JObject.FromObject(server);
                result["Password"] = "******";
                result.Remove("ChannelItems");
                return result.ToResponse();
            }
            return ApiResponse<JObject>.Fail();
        }

        [WebApi("获取RabbitMQ队列中MES有关的队列信息", "", "返回ApiResult")]
        public ApiResponse<List<MesQueuesModel>> GetMesQueuesName(string ContainsName)
        {
            if (string.IsNullOrEmpty(ContainsName))
                return ApiResponse<List<MesQueuesModel>>.Fail("传入值有误！"); ;

            List<MesQueuesModel> resultDatas = new List<MesQueuesModel>();
            foreach (RabbitHost host in _server.RabbitMQManager.Hosts)
            {
                MesQueuesModel data = new MesQueuesModel();

                //获取具有关键字的队列名称
                data.MaterialTopic = (from c in host.Channels.Values
                                      where ((RabbitChannel)c).QueueName.Contains(ContainsName)
                                      select ((RabbitChannel)c).QueueName).ToList();

                if (!data.MaterialTopic.Any())
                    continue;

                //赋值
                ConfigReflectionHelper.AutoMapping(data, host.HostConfig, "ChannelItems,Item,FullName");
                resultDatas.Add(data);
            }

            return resultDatas.ToResponse();
        }

        [WebApi("新增RabbitMQ通道", "主机名称,通道对象", "返回ApiResult")]
        public ApiResponse<string> AddRabbiMQChannel(string hostFullName, RabbitChannelConfig channelItem)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                server.Add(channelItem);
                return ApiResponse<string>.Success("新增成功！");
            }
            return ApiResponse<string>.Fail("未找到该主机，新增通道失败！");
        }

        [WebApi("删除RabbitMQ通道", "主机名称,通道名称", "返回ApiResult")]
        public ApiResponse<string> DelRabbiMQChannel(string hostFullName, string channelFullName)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                var channel = server.ChannelItems.Values.FirstOrDefault(c => c.FullName == channelFullName);
                if (channel == null) return ApiResponse<string>.Fail("未找到主机或通道，删除通道失败！");
                server.ChannelItems.Remove(channel);
                return ApiResponse<string>.Success("删除成功！");
            }
            return ApiResponse<string>.Fail("未找到主机或通道，删除通道失败！");
        }

        [WebApi("修改RabbitMQ通道", "主机名称,通道名称,通道对象", "返回ApiResult")]
        public ApiResponse<string> UpdateRabbiMQChannel(string hostFullName, string channelFullName, RabbitChannelConfig newChannel)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                Helper.Validation.ValidationMain.ScanIsValid(newChannel);
                var channelOld = server.ChannelItems.Values.FirstOrDefault(a => a.FullName == channelFullName);
                if (channelOld == null) return ApiResponse<string>.Fail("未找到通道，修改失败！");
                ConfigReflectionHelper.AutoMapping(channelOld, newChannel, "FullName");
                return ApiResponse<string>.Success("更新成功");
            }
            return ApiResponse<string>.Fail("未找到主机，修改失败！");
        }

        [WebApi("获取RabbitMQ通道", "主机名称,通道名称", "返回ApiResult")]
        public ApiResponse<List<RabbitChannelConfig>> GetRabbiMQChannel(string hostFullName, string groupKey)
        {
            if (_project.Objects[hostFullName] is RabbitHostConfig server)
            {
                return server.ChannelItems.Values.Where(x => x.GroupKey == groupKey).ToList().ToResponse();
            }
            return ApiResponse<List<RabbitChannelConfig>>.Fail("未找到该主机，查询失败！");
        }

        [WebApi("获取读写模式", "", "返回数据类型对象集合")]
        public ApiResponse<List<EnumEntity>> GetRoles()
        {
            return EnumToArrays.EnumToArray<Roles>().ToResponse();
        }

        [WebApi("获取发送方式", "", "返回数据类型对象集合")]
        public ApiResponse<List<EnumEntity>> GetSendMethod()
        {
            return EnumToArrays.EnumToArray<SendMethod>().ToResponse();
        }

        [WebApi("获取系统版本环境", "", "返回配置文件对象")]
        public ApiResponse<string> GetSysEnvironment()
        {
            var Config = _server.Config.Description;
            return Config.ToResponse();
        }

        [WebApi("获取DataCenter配置文件", "", "返回配置文件对象")]
        public ApiResponse<DataCenterConfig> GetDataCenterConfig()
        {
            var obj = BasicServiceManager.GetProjService().Project.Objects;
            var Config = _server.Config;
            return Config.ToResponse();
        }

        [WebApi("获取API配置", "", "返回配置文件对象")]
        public ApiResponse<WebAPIConfig> GetAPIConfig()
        {
            WebAPIConfig WebAPIConfig = _server.Config.WebAPIConfig;
            return WebAPIConfig.ToResponse();
        }

        [WebApi("获取Mimio配置", "", "返回配置文件对象")]
        public ApiResponse<MinioConfig> GetMinioConfig()
        {
            MinioConfig MinioConfig = _server.Config.MinioConfig;
            return MinioConfig.ToResponse();
        }

        [WebApi("获取系统配置文件", "", "返回配置文件对象")]
        public ApiResponse<SystemCfg> GetSystemConfig()
        {
            SystemCfg Sysconfig = SystemCfgService.GetInstance().SystemCfg;
            return Sysconfig.ToResponse();
        }

        [WebApi("修改系统配置文件", "键,值", "返回配置文件对象")]
        public ApiResponse<string> SetSystemConfig(SysConfigModel[] models)
        {
            var config = SystemCfgService.GetInstance().SystemCfg;
            foreach (var item in models)
            {
                ConfigReflectionHelper.UpdateValueByPath(config, item.Key, item.Value);
            }
            SystemCfgService.GetInstance().Save(config);
            return ApiResponse<string>.Success("修改成功！");
        }

        [WebApi("修改DataCenter配置文件", "配置的Key,配置的Value", "返回布尔类型")]
        public ApiResponse<string> SetDataCenterConfig(SysConfigModel[] models)
        {
            var config = _server.Config;
            foreach (var item in models)
            {
                ConfigReflectionHelper.UpdateValueByPath(config, item.Key, item.Value);
            }
            _server.Save();
            return ApiResponse<string>.Success("修改成功！");
        }

        [WebApi("保存配置到文件", "", "返回true或false")]
        public ApiResponse<string> SaveConfig()
        {
            if (_server.Save())
                return ApiResponse<string>.Success("修改成功！");
            else
                return ApiResponse<string>.Fail("修改失败！");
        }

        [WebApi("加密字符", "值,接口密码", "加密后的字符")]
        public ApiResponse<string> Encode(string value, int password)
        {
            if (password != 6)
                return "非研发人员禁止使用！".ToResponse();
            return Encryption.Encode(value).ToResponse();
        }

        [WebApi("解密字符", "值,接口密码", "解密后的字符")]
        public string Decode(string value, int password)
        {
            if (password != 6)
                return "非研发人员禁止使用！";
            return Encryption.Decode(value);
        }

        [WebApi("获取IP地址", "", "IP地址")]
        public string GetLocalIP()
        {
            return IPUtil.GetLocalIP();
        }

        [WebApi("获取网关信息", "", "IP地址")]
        public object GetGateWayInfo()
        {
            var project = ProjService.GetInstance().Project;
            var result = new
            {
                NumberOfDriverLicenses = (RpcProcessor.ExecutionAction("Device", "GetAuthorizationNumber", new object[] { }) as ApiResponse<int>)?.Data ?? 0,
                ProjectName = project.Name,
                OSVersion = Helper.OS.IotEnvironment.OSCommand.GetOSDescription(),
                IPV4 = IPUtil.GetLocalIP() ?? "",
                ProjectFullPath = project.ProjectFullPath,
                IsRunning = project.IsRunning,
                SN = Machine.MachineCode,
                FileVersion = AppCommonString.FileVersion,
                MachineName = Environment.MachineName,//电脑名称
                Modules = project.PlugIns.Values.Select(p => p.Name).ToList(),
                Version = GetIOTVersion()
            };
            return result;
        }

        [WebApi("获取IOT版本信息", "", "IP地址")]
        public string GetIOTVersion()
        {
            try
            {
                var filePath = Path.Combine(System.Environment.CurrentDirectory, "Release.cfg");
                if (!File.Exists(filePath))
                {
                    Logger.Warn("未找到IOT发布文件，版本信息获取失败！");
                    return "";
                }
                var lines = File.ReadAllLines(filePath);
                if (lines.Length > 0)
                {
                    return lines[0].Split(':')[1].Trim();
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorException(ex);
            }
            return "";
        }

        [WebApi("远程命令测试", "", "IP地址")]
        public object RemoteTest(string ip)
        {
            var _rpcClient = new RpcClient(ip, 9100);
            RpcPara request = new RpcPara
            {
                MethodName = "ReceiveHeartbeat",
                Paras = new object[] { },
            };
            var res = _rpcClient.Call<InvokeMsg>(request);
            _rpcClient.Dispose();
            return res;
        }
    }
}